//==============================================================================
/**
 * @file	fldeff_fchg.c
 * @brief	フォルムチェンジエフェクト
 * @author	saito
 * @data	09.03.25
 */
//==============================================================================
#include "common.h"
#include "fieldsys.h"
#include "field_effect.h"
#include "fieldobj.h"
#include "fldeff_fchg.h"

#include "..\system/snd_tool.h"

#include "field_3dobj.h"

#define ANM_NUM	(2)

//--------------------------------------------------------------
///	FE_FCHG型
//--------------------------------------------------------------
typedef struct _TAG_FE_FCHG * FE_FCHG_PTR;

typedef struct _TAG_FE_FCHG
{
	FE_SYS *fes;
	NNSFndAllocator Allocator;

	FLD_3DOBJ_MDL	Mdl;
	FLD_3DOBJ_ANM	Anm[ANM_NUM];
	FLD_3DOBJ		Obj;
}FE_FCHG;

typedef struct
{
	FE_SYS *fes;								///<FE_SYS_PTR
	FE_FCHG_PTR fchg;							///<FE_FCHG_PTR
}FCHG_ADD_H;

typedef struct
{
	int EndFlg;
	FE_FCHG_PTR FChgPtr;
}FCHG_WORK;


#define FCHG_ADD_H_SIZE (sizeof(FCHG_ADD_H))
#define FE_FCHG_SIZE (sizeof(FE_FCHG))
#define FCHG_WORK_SIZE (sizeof(FCHG_WORK))

//==============================================================================
//	プロトタイプ
//==============================================================================
static void GraphicInit( FE_FCHG_PTR fchg );
static void GraphicDelete( FE_FCHG_PTR fchg );

static BOOL AnimeNoLoop(FLD_3DOBJ_ANM *anm, const u8 inNum);
static void SetAnmFrame(FLD_3DOBJ_ANM *anm, const u8 inNum, const u32 inFrame);

static int EoaFChg_Init( EOA_PTR eoa, void *wk );
static void EoaFChg_Delete( EOA_PTR eoa, void *wk );
static void EoaFChg_Move( EOA_PTR eoa, void *wk );
static void EoaFChg_Draw( EOA_PTR eoa, void *wk );

static const EOA_H_NPP DATA_EoaH_FChg =
{
	FCHG_WORK_SIZE,
	EoaFChg_Init,
	EoaFChg_Delete,
	EoaFChg_Move,
	EoaFChg_Draw,
};


//--------------------------------------------------------------
/**
 * 初期化
 * @param	fes		FE_SYS_PTR
 * @retval	FE_FCHG_PTR
 */
//--------------------------------------------------------------
void * FE_FChg_Init( FE_SYS *fes )
{
	FE_FCHG_PTR fchg;

	fchg = FE_AllocClearMemory( fes, FE_FCHG_SIZE, ALLOC_FR, 0 );
	fchg->fes = fes;

	GraphicInit( fchg );
	OS_Printf("adr=%x\n",fchg);

	return( fchg );
}

//--------------------------------------------------------------
/**
 * 削除
 * @param	work		ワークポインタ
 * @retval	nothing
 */
//--------------------------------------------------------------
void FE_FChg_Delete( void *work )
{
	FE_FCHG_PTR fchg = work;
	GraphicDelete( fchg );
	FE_FreeMemory( fchg );
}

//--------------------------------------------------------------
/**
 * グラフィック初期化
 * @param	fchg	FE_FCHG_PTR
 * @retval	nothing
 */
//--------------------------------------------------------------
static void GraphicInit( FE_FCHG_PTR fchg )
{
	int heapid = HEAPID_FIELD;

	// アロケーター作成
	sys_InitAllocator( &fchg->Allocator, heapid, 32 );

	//モデルロード
	FLD_3DObjMdlLoad(&fchg->Mdl, ARC_FLDEFF, NARC_fldeff_e_sheimi_nsbmd, heapid);

	//アニメデータロード
	FLD_3DObjAnmLoad(&fchg->Anm[0], &fchg->Mdl, ARC_FLDEFF, NARC_fldeff_e_sheimi_nsbma,
		heapid, &fchg->Allocator );
	FLD_3DObjAnmLoad(&fchg->Anm[1], &fchg->Mdl, ARC_FLDEFF, NARC_fldeff_e_sheimi_nsbca,
		heapid, &fchg->Allocator );


	//描画オブジェクト初期化
	FLD_3DObjInit( &fchg->Obj, &fchg->Mdl );

	//アニメをリンク
	FLD_3DObjAddAnm( &fchg->Obj, &fchg->Anm[0] );
	FLD_3DObjAddAnm( &fchg->Obj, &fchg->Anm[1] );

	//フレームセット
	SetAnmFrame(fchg->Anm, ANM_NUM, 0);
/**
	//座標セット
	{
		VecFx32 vec;
		FieldOBJ_VecPosGet( Player_FieldOBJGet( fsys->player ), &vec );
		vec.x += (EYE_POS_X*FX32_ONE);
		vec.y += (EYE_POS_Y*FX32_ONE);
		vec.z += (EYE_POS_Z*FX32_ONE);
		FLD_3DObjSetMatrix( &outWork->ObjEyes, vec.x, vec.y, vec.z );
	}
*/
	//描画フラグ設定	(非表示)
	FLD_3DObjSetDraw( &fchg->Obj, FALSE );
}

//--------------------------------------------------------------
/**
 * グラフィック削除
 * @param	fchg	FE_FCHG_PTR
 * @retval	nothing
 */
//--------------------------------------------------------------
static void GraphicDelete( FE_FCHG_PTR fchg )
{

	//アニメデータ破棄
	FLD_3DObjAnmDelete( &fchg->Anm[1], &fchg->Allocator);
	FLD_3DObjAnmDelete( &fchg->Anm[0], &fchg->Allocator);
	//モデルデータ破棄
	FLD_3DObjMdlDelete( &fchg->Mdl);
}

//--------------------------------------------------------------
/**
 * 追加
 * @param	fes			FE_SYS *
 * @param	mtx			表示位置
 * @retval	EOA_PTR		追加EOA_PTR
 */
//--------------------------------------------------------------
EOA_PTR FE_FChg_Add( FE_SYS *fes, const VecFx32 *mtx)
{
	int pri;
	FCHG_ADD_H head;
	EOA_PTR eoa;

	head.fes = fes;
	head.fchg = FE_EffectWorkGet( fes, FE_FLD_FCHG );
	OS_Printf("adr=%x\n",head.fchg);
	eoa = FE_EoaAddNpp( fes, &DATA_EoaH_FChg, mtx, 0, &head, 0xff );
	return( eoa );
}

//--------------------------------------------------------------
/**
 * 終了チェック
 * @param	eoa		EOA
 * @retval	int		TRUE=終了
 */
//--------------------------------------------------------------
int FE_FChg_EndCheck( EOA_PTR eoa )
{
	FCHG_WORK *work;

	work = EOA_LocalWorkGet( eoa );
	return( work->EndFlg );
}

//--------------------------------------------------------------
/**
 * EOA 初期化
 * @param	eoa		EOA_PTR
 * @param	wk		eoa work *
 * @retval	int		TRUE=正常終了。FALSE=異常終了
 */
//--------------------------------------------------------------
static int EoaFChg_Init( EOA_PTR eoa, void *wk )
{
	const FCHG_ADD_H *head;
	FE_FCHG_PTR ptr;
	FCHG_WORK *work;
	head = EOA_AddPtrGet( eoa );
	work = wk;
	work->FChgPtr = head->fchg;
	work->EndFlg = 0;

	ptr = head->fchg;
	OS_Printf("headadr=%x\n",head);
	OS_Printf("adr=%x\n",head->fchg);
	OS_Printf("adr=%x\n",ptr);

	//フレームセット
	SetAnmFrame(ptr->Anm, ANM_NUM, 0);
	//描画フラグ設定	(表示)
	FLD_3DObjSetDraw( &ptr->Obj, TRUE );
	//座標セット
	{
		VecFx32 vec;
		EOA_MatrixGet( eoa, &vec );
		FLD_3DObjSetMatrix( &ptr->Obj, vec.x, vec.y, vec.z );
	}
	OS_Printf("adr=%x\n",ptr);

	//ＳＥ再生
	Snd_SePlay( SEQ_SE_GS_TUREARUKI );

	return( TRUE );
}

//--------------------------------------------------------------
/**
 * EOA　動作
 * @param	eoa		EOA_PTR
 * @param	wk		eoa work *
 * @retval	nothing
 */
//--------------------------------------------------------------
static void EoaFChg_Move( EOA_PTR eoa, void *wk )
{
	FCHG_WORK *work;
	work = wk;
/**
	if (work->EndFlg){
		EOA_Delete( eoa );
	}
*/
}

//--------------------------------------------------------------
/**
 * EOA　削除
 * @param	eoa		EOA_PTR
 * @param	wk		eoa work *
 * @retval	nothing
 */
//--------------------------------------------------------------
static void EoaFChg_Delete( EOA_PTR eoa, void *wk )
{
	FE_FCHG_PTR ptr;
	FCHG_WORK *work;

	work = wk;
	ptr =work->FChgPtr;

	//描画フラグ設定	(非表示)
	FLD_3DObjSetDraw( &ptr->Obj, FALSE );
}

//--------------------------------------------------------------
/**
 * EOA 描画
 * @param	eoa		EOA_PTR
 * @param	wk		eoa work *
 * @retval	nothing
 */
//--------------------------------------------------------------
static void EoaFChg_Draw( EOA_PTR eoa, void *wk )
{
	VecFx32 vec;
	FE_FCHG_PTR fchg;
	FCHG_WORK *work;
	work = wk;
	fchg = work->FChgPtr;
	OS_Printf("adr=%x\n",fchg);

	if ( AnimeNoLoop( fchg->Anm, ANM_NUM ) ){
		//アニメ終了
		work->EndFlg = 1;
	}
	//描画
	FLD_3DObjDraw( &fchg->Obj );
}

//==============================================================================
/**
 * アニメフレーム更新関数
 *
 * @param	anm			アニメポインタ配列
 * @param	inNum		アニメ数
 *
 * @retval  BOOL		TRUE：アニメ終了	FALSE：アニメ継続
 */
//==============================================================================
static BOOL AnimeNoLoop(FLD_3DOBJ_ANM *anm, const u8 inNum)
{
	u8 i;
	BOOL end;
	u8 end_num = 0;
	for (i=0;i<inNum;i++){
		end = FLD_3DObjAnmNoLoop( &anm[i], FX32_ONE );
		if (end){
			OS_Printf("%d:アニメ終了\n",i);
			end_num++;
		}
	}
	if (end_num == inNum){
		return TRUE;
	}

	return FALSE;
}

//==============================================================================
/**
 * アニメフレームセット
 *
 * @param	anm			アニメポインタ配列
 * @param	inNum		アニメ数
 * @param	inFrame		フレーム
 *
 * @retval  none
 */
//==============================================================================
static void SetAnmFrame(FLD_3DOBJ_ANM *anm, const u8 inNum, const u32 inFrame)
{
	u8 i;
	for (i=0;i<inNum;i++){
		FLD_3DObjAnmSet( &anm[i], inFrame  );
	}
}


